/*******************************************************************************
 * Witz - Winboard Chess Engine                                                *
 * DATABASEGEN.C                                                               *
 *                                                                             *
 * Generates databases required throughout the program                         *
 * The generation should take less than 5 hundreths of a second                *
 *                                                                             *
 * Please refer to the licence notice in MAIN.C                                *
 *                                                                             *
 * Copywright (C) 2006 Pradu Kannan                                            *
 * http://witz.sf.net/                                                         *
 ******************************************************************************/

#include "build.h"
#include "defs.h"
#include "protos.h"
#include "data.h"

/*Format of the rotated bits - A1 is LSB and H8 is MSB
toBit[i]
A8 B8 C8 D8 E8 F8 G8 H8
A7 B7 C7 D7 E7 F7 G7 H7
A6 B6 C6 D6 E6 F6 G6 H6
A5 B5 C5 D5 E5 F5 G5 H5
A4 B4 C4 D4 E4 F4 G4 H4
A3 B3 C3 D3 E3 F3 G3 H3
A2 B2 C2 D2 E2 F2 G2 H2
A1 B1 C1 D1 E1 F1 G1 H1

toBitL90[i]
H8 H7 H6 H5 H4 H3 H2 H1
G8 G7 G6 G5 G4 G3 G2 G1
F8 F7 F6 F5 F4 F3 F2 F1
E8 E7 E6 E5 E4 E3 E2 E1
D8 D7 D6 D5 D4 D3 D2 D1
C8 C7 C6 C5 C4 C3 C2 C1
B8 B7 B6 B5 B4 B3 B2 B1
A8 A7 A6 A5 A4 A3 A2 A1

toBitR45[i]
C7 D8 A6 B7 C8 A7 B8 A8
F8 A4 B5 C6 D7 E8 A5 B6
E6 F7 G8 A3 B4 C5 D6 E7
E5 F6 G7 H8 A2 B3 C4 D5
E4 F5 G6 H7 A1 B2 C3 D4
D2 E3 F4 G5 H6 B1 C2 D3
G3 H4 D1 E2 F3 G4 H5 C1
H1 G1 H2 F1 G2 H3 E1 F2

toBitL45[i]
G6 H5 F8 G7 H6 G8 H7 H8
H3 D8 E7 F6 G5 H4 E8 F7
F4 G3 H2 C8 D7 E6 F5 G4
E4 F3 G2 H1 B8 C7 D6 E5
D4 E3 F2 G1 A8 B7 C6 D5
B5 C4 D3 E2 F1 A7 B6 C5
C2 D1 A5 B4 C3 D2 F1 A6
A1 A2 B1 A3 B2 C1 A4 B3
*/


//Converts to rotated bits
U64 toBit[64];		//rank
U64 toBitL90[64];	//file
U64 toBitR45[64];	//a1h8
U64 toBitL45[64];	//h1a8

//Finds the shift needed to get an occupancy
U64 rankshift[64];  //rank
U64 fileshift[64];  //file
U64 a1h8shift[64];  //a1h8
U64 h1a8shift[64];  //h1a8

//Sliding Piece move database
U64 rankmoves[64][256];  //rank
U64 filemoves[64][256];  //file
U64 a1h8moves[64][256];  //a1h8
U64 h1a8moves[64][256];  //h1a8

//Pawn moves, King moves, and Knight moves
U64 Pmoves[2][64];  //Pawn moves
U64 Pcaps[2][64];   //Pawn captures
U64 Kmoves[64];     //King moves
U64 Nmoves[64];     //Knight moves

//PlusN and MinusN bitmaps
U64 plus1[64], plus7[64], plus8[64], plus9[64];
U64 minus1[64], minus7[64], minus8[64], minus9[64];

//gives a ray in the direction from-->to
//ray[from][to][occupancy]
U64 ray[64][64][256];

//16 bit log table
char LogTable[65536];

//16 bit population table
char population[65536];

//Zobrist Keys [side][piece][square]
U64 zobrist[2][NUMPIECETYPES][64];
//Zobrist Castling Keys [side][castling side]
U64 zobristCastling[2][2];
//zobrist Key for EP
U64 zobristEP[64];

//all in terms of [side]
char castlnigShift[2]={0,56};
char castlingPrivilageShift[2]={0,2};
int doubleMove[2]={16,-16};
int doubleMove2[2]={8,-8};
int pawnEPset[2]={-8,8};
int signSide[2]={1,-1};

//the seventh rank for pawns for each side
U64 rank7[2]={0x00FF000000000000ULL,0x000000000000FF00ULL};

//all in terms of [castlingside]
move castlingMoves[2]={encodePiece(K)+encodeKingsideCastle,encodePiece(K)+encodeQueensideCastle};
char castlingAnds[2]={0x60,0xE};
//castlingXors[side][castlingside][0-K, 1-R]
U64  castlingXors[2][2][2]=
{
	{
		{U64EMPTY,U64EMPTY},
		{U64EMPTY,U64EMPTY}
	},
	{
		{U64EMPTY,U64EMPTY},
		{U64EMPTY,U64EMPTY}
	},
};

//castlingRotatedXors[side][castling side][0-All, 1-L90, 2-L45, 3-R45]
U64 castlingRotatedXors[2][2][4]=
{
	{
		{U64EMPTY,U64EMPTY,U64EMPTY,U64EMPTY},
		{U64EMPTY,U64EMPTY,U64EMPTY,U64EMPTY}
	},
	{
		{U64EMPTY,U64EMPTY,U64EMPTY,U64EMPTY},
		{U64EMPTY,U64EMPTY,U64EMPTY,U64EMPTY}
	}
};

//castlingSquaresK[side][castlingside][0-from 1-to]
char castlingSquaresK[2][2][2]=
{
	{
		{4,6},
		{4,2}
	},
	{
		{60,62},
		{60,58}
	}
};

//castlingSquaresK[side][castlingside][0-from 1-to]
char castlingSquaresR[2][2][2]=
{
	{
		{7,5},
		{0,3}
	},
	{
		{63,61},
		{56,59}
	}
};

//castlingBits[side][castlingside]
char castlingBits[2][2]=
{
	{WK,WQ},
	{BK,BQ}
};

//notCastlingBits[side][castlingside]
char notCastlingBits[2][2]=
{
	{WQ|BK|BQ,WK|BK|BQ},
	{WK|WQ|BQ,WK|WQ|BK}
};

//castling<CASTLINGSIDE>RookFrom[SIDE]
char castlingQRookFrom[2]={0,56};
char castlingKRookFrom[2]={7,63};

//allCastlingBitsSide[side]
char allCastlingBitsSide[2]={WCASTLE,BCASTLE};
char notAllCastlingBitsSide[2]={BCASTLE,WCASTLE};

//castlingPassover[side][castlingside] - Bits where the king passes over in castling
U64 castlingPassover[2][2]=
{
	{0x3ULL<<5,0x3ULL<<2},
	{0x3ULL<<(56+5),0x3ULL<<(56+2)}
};

//castlingPassover[side][castlingside] - Bits which need to be tested empty
U64 castlingEmptySquares[2][2]=
{
	{0x3ULL<<5,0x7ULL<<1},
	{0x3ULL<<(56+5),0x7ULL<<(56+1)}
};

//String representation of a side
char* sideToStr[3]={"White", "Black", "No Side"};
//String representation of a win
char* winToStr[2]={"1-0","0-1"};
//Charecter representation of a piec
char pieceToStr[NUMPIECETYPES] = {'O','P','N','B','R','Q','K'};

//A Flip array that flips a square index into a square index from the other side
char flip[64] = {
	63, 62, 61, 60, 59, 58, 57, 56,
	55, 54, 53, 52, 51, 50, 49, 48,
	47, 46, 45, 44, 43, 42, 41, 40,
	39, 38, 37, 36, 35, 34, 33, 32,
	31, 30, 29, 28, 27, 26, 25, 24,
	23, 22, 21, 20, 19, 18, 17, 16,
	15, 14, 13, 12, 11, 10,  9,  8,
	 7,  6,  5,  4,  3,  2,  1,  0
};

//Evaluvation Specific

//[square][1-side is equal to side to play 0 otherwise]
U64 kingStopsWHITEPasser[64][2];
U64 kingStopsBLACKPasser[64][2];

//distance[from][to]
int distance[64][64];

/*generateDatabases()
 *generates all databases required for the program in the correct order
 */
void generateDatabases()
{
	//seed Mersenne Twister with default values
	seedMT();

	generateToBitsandShifts();
	generateCastlingBits();
	generateSilderBitBase();
	generateKNPmoves();
	generatePlusNMinusN();
	generateLogTable();
	generatePopulation();
	generateZobrist();
	generateSEEdir();
	generateSEEocc();
	generateSEEpiece();
	generateKingStopsPasser();
	generateDistance();
}

/*generateToBitsandShifts()
 *To bit and shift initializing
 */
void generateToBitsandShifts()
{
	int i,j;
	toBit[0]=((U64)1);
	for(i=0;i<64;i++)
	{
		toBit[i]=toBit[0]<<i;
		toBitL90[i]=toBit[0]<<((7-(i/8))+8*(i%8));
		rankshift[i]=i & 0x38;
		fileshift[i]=(i%8)*8;
	}
	for(i=0;i<8;i++)
		for(j=0;j<=i;j++)
		{
			toBitL45[8*i-7*j]=toBit[(i*(i+1))/2+j];
			toBitL45[63-8*i+7*j]=toBit[63-(i*(i+1))/2-j];
			toBitR45[7-i+9*j]=toBit[(i*(i+1))/2+j];
			toBitR45[56+i-9*j]=toBit[63-(i*(i+1))/2-j];
			h1a8shift[8*i-7*j]=(i*(i+1))/2;
			h1a8shift[63-8*i+7*j]=63-(i*(i+3))/2;
			a1h8shift[7-i+9*j]=(i*(i+1))/2;
			a1h8shift[56+i-9*j]=63-(i*(i+3))/2;
		}
}

/*generateSliderBitBase()
 *generates slider bit bases
 */
void generateSilderBitBase()
{
	//initialize sliding bit bases to 0
	int i,j,k;
	for(i=0;i<64;i++)
		for(j=0;j<256;j++)
			rankmoves[i][j]=filemoves[i][j]=a1h8moves[i][j]=h1a8moves[i][j]=U64EMPTY;

	//generate rankmoves[][], filemoves[][], a1h8moves[][] and h1a8moves[][]
	for(i=0;i<256;i++)
		for(j=0;j<8;j++)
		{
			for(k=j+1;k<8;k++)
			{
				rankmoves[j][i]|=toBit[k];
				filemoves[56-8*j][i]|=toBit[56-8*k];
				a1h8moves[9*j][i]|=toBit[9*k];
				h1a8moves[56-7*j][i]|=toBit[56-7*k];
				if(toBit[k]&((U64)i))
					break;
			}
			for(k=j-1;k>=0;k--)
			{
				rankmoves[j][i]|=toBit[k];
				filemoves[56-8*j][i]|=toBit[56-8*k];
				a1h8moves[9*j][i]|=toBit[9*k];
				h1a8moves[56-7*j][i]|=toBit[56-7*k];
				if(toBit[k]&((U64)i))
					break;
			}
			for(k=1;k<8;k++)
			{
				rankmoves[j+8*k][i]=rankmoves[j][i]<<(8*k);
				filemoves[56-8*j+k][i]=filemoves[56-8*j][i]<<k;
				if(((9*j+k) & 0x38) == ((9*j) & 0x38))
				{
					a1h8moves[9*j+k][i]=(a1h8moves[9*j][i]<<k) & (U64FULL>>(8*k));
					h1a8moves[56-7*j+k][i]=(h1a8moves[56-7*j][i]<<k) & (U64FULL<<(8*k+1));
				}
				if((9*j+8*k)<64)
				{
					a1h8moves[9*j+8*k][i]=(a1h8moves[9*j][i]<<(8*k));
					h1a8moves[56-7*j-8*k][i]=(h1a8moves[56-7*j][i])>>(8*k);
				}
			}
		}
}

/*generateKNPmoves()
 *generates King, Knight, and Pawn moves
 */
void generateKNPmoves()
{
	int i;
	for(i=0;i<64;i++)
	{
		Pmoves[BLACK][i]=(toBit[i])>>8;
		Pmoves[WHITE][i]=(toBit[i])<<8;
		Pcaps[BLACK][i]=Pcaps[WHITE][i]=Kmoves[i]=Nmoves[i]=U64EMPTY;
		if((i & 0x38)== ((i+1) & 0x38))
		{
			Kmoves[i]|=toBit[i+1];
			Pcaps[BLACK][i]|=toBit[i]>>7;
			Pcaps[WHITE][i]|=toBit[i]<<9;
			if((i & 0x38)== ((i+2) & 0x38))
				Nmoves[i]|=(toBit[i]>>6)|(toBit[i]<<10);
		}
		if((i & 0x38)== ((i-1) & 0x38))
		{
			Kmoves[i]|=toBit[i-1];
			Pcaps[BLACK][i]|=toBit[i]>>9;
			Pcaps[WHITE][i]|=toBit[i]<<7;
			if((i & 0x38)== ((i-2) & 0x38))
				Nmoves[i]|=(toBit[i]<<6)|(toBit[i]>>10);
		}
		Kmoves[i]|=Pmoves[BLACK][i]|Pmoves[WHITE][i]|Pcaps[BLACK][i]|Pcaps[WHITE][i];
		Nmoves[i]|=(Pcaps[BLACK][i]>>8)|(Pcaps[WHITE][i]<<8);
	}
}

/*generatePlusNMinusN()
 *generates plusN and minusN bitmaps
 */
void generatePlusNMinusN()
{
	int i,j;
	for(i=0;i<8;i++)
	{
		plus1[i]=minus1[i]=plus8[56-8*i]=minus8[56-8*i]=plus9[9*i]=minus9[9*i]=plus7[56-7*i]=minus7[56-7*i]=U64EMPTY;
		for(j=i+1;j<8;j++)
		{
			plus1[i]|=toBit[j];
			minus8[56-8*i]|=toBit[56-8*j];
			plus9[9*i]|=toBit[9*j];
			minus7[56-7*i]|=toBit[56-7*j];
		}
		for(j=i-1;j>=0;j--)
		{
			minus1[i]|=toBit[j];
			plus8[56-8*i]|=toBit[56-8*j];
			minus9[9*i]|=toBit[9*j];
			plus7[56-7*i]|=toBit[56-7*j];
		}
		for(j=1;j<8;j++)
		{
			plus1[i+8*j]=plus1[i]<<(8*j);
			minus1[i+8*j]=minus1[i]<<(8*j);
			plus8[56-8*i+j]=plus8[56-8*i]<<j;
			minus8[56-8*i+j]=minus8[56-8*i]<<j;
			if(((9*i+j) & 0x38)==((9*i) & 0x38))
			{
				plus9[9*i+j]=(plus9[9*i]<<j)&(U64FULL>>(8*j));
				minus9[9*i+j]=(minus9[9*i]<<j)&(U64FULL>>(8*j));
				plus7[56-7*i+j]=(plus7[56-7*i]<<j)&(U64FULL<<(8*j+1));
				minus7[56-7*i+j]=(minus7[56-7*i]<<j)&(U64FULL<<(8*j+1));
			}
			if((9*i+8*j)<64)
			{
				plus9[9*i+8*j]=(plus9[9*i]<<(8*j));
				minus9[9*i+8*j]=(minus9[9*i]<<(8*j));
				plus7[56-7*i-8*j]=(plus7[56-7*i]>>(8*j));
				minus7[56-7*i-8*j]=(minus7[56-7*i]>>(8*j));
			}
		}
	}
}

/*generateLogTable()
 *generates the Log Table used for FirstOne LastOne
 */
void generateLogTable()
{
	int i,j;
	LogTable[0]=-1;
	for(i=1;i<65536;i++)
	{
		for(j=15;j>=0 && !((1<<j)&i);j--);
		LogTable[i]=j;
	}
}

/*generatePopulation()
 *generates the population table for population counts
 */
void generatePopulation()
{
     unsigned int i,j;
     for(i=0;i<=0xFFFF;i++)
          population[i]=0;
     for(i=0;i<=0xFFFF;i++)
          for(j=0;j<16;j++)
               if((1<<j)&i)
                    population[i]++;
}


/*generateZobrist()
 *generates random Zobrist keys
 */
void generateZobrist()
{
	int i,j,k;
	for(k=0;k<64;k++)
	{
		zobristEP[k]=rand64();
		for(i=0;i<2;i++)
			for(j=0;j<NUMPIECETYPES;j++)
				zobrist[i][j][k]=rand64();
	}
	zobristCastling[WHITE][KINGSIDE]=zobrist[WHITE][K][4]^zobrist[WHITE][K][6]^zobrist[WHITE][R][7]^zobrist[WHITE][R][5];
	zobristCastling[WHITE][QUEENSIDE]=zobrist[WHITE][K][4]^zobrist[WHITE][K][2]^zobrist[WHITE][R][0]^zobrist[WHITE][R][3];
	zobristCastling[BLACK][KINGSIDE]=zobrist[BLACK][K][60]^zobrist[BLACK][K][62]^zobrist[BLACK][R][63]^zobrist[BLACK][R][64];
	zobristCastling[BLACK][QUEENSIDE]=zobrist[BLACK][K][60]^zobrist[BLACK][K][58]^zobrist[BLACK][R][56]^zobrist[BLACK][R][59];
}

/*generateCastlingBits()
 *initializes databases needed for castling
 *must be called after generating toBits and shifts
 */
void generateCastlingBits()
{
	int i, j;
	for(i=0;i<2;i++)
		for(j=0;j<2;j++)
		{
			castlingXors[i][j][0]=toBit[castlingSquaresK[i][j][0]]^toBit[castlingSquaresK[i][j][1]];
			castlingXors[i][j][1]=toBit[castlingSquaresR[i][j][0]]^toBit[castlingSquaresR[i][j][1]];
			castlingRotatedXors[i][j][0]=castlingXors[i][j][0]|castlingXors[i][j][1];
			castlingRotatedXors[i][j][1]=(toBitL90[castlingSquaresK[i][j][0]]^toBitL90[castlingSquaresK[i][j][1]])|(toBitL90[castlingSquaresR[i][j][0]]^toBitL90[castlingSquaresR[i][j][1]]);
			castlingRotatedXors[i][j][2]=(toBitL45[castlingSquaresK[i][j][0]]^toBitL45[castlingSquaresK[i][j][1]])|(toBitL45[castlingSquaresR[i][j][0]]^toBitL45[castlingSquaresR[i][j][1]]);
			castlingRotatedXors[i][j][3]=(toBitR45[castlingSquaresK[i][j][0]]^toBitR45[castlingSquaresK[i][j][1]])|(toBitR45[castlingSquaresR[i][j][0]]^toBitR45[castlingSquaresR[i][j][1]]);
		}
}


/*generateSEEdir()
 *generates the bit that will be used for SEE to generate ray-attackers
 *also generates the ray[64][64][256] in the process
 */
void generateSEEdir()
{
	char from,target;
	int occ;
	U64 temp;
	for(from=0;from<64;from++)
		for(target=0;target<64;target++)
			for(occ=0;occ<=255;occ++)
			{
				if(ROW(from)>ROW(target))
				{
					if(COL(from)<COL(target))
					{
						ray[target][from][occ]=temp=plus7[from]&h1a8moves[from][occ];
						if(temp)
							SEEdir[from][target][occ]=LastOne(temp);
						else
							SEEdir[from][target][occ]=-1;
					}
					else if(COL(from)==COL(target))
					{
						ray[target][from][occ]=temp=plus8[from]&filemoves[from][occ];
						if(temp)
							SEEdir[from][target][occ]=LastOne(temp);
						else
							SEEdir[from][target][occ]=-1;
					}
					else
					{
						ray[target][from][occ]=temp=plus9[from]&a1h8moves[from][occ];
						if(temp)
							SEEdir[from][target][occ]=LastOne(temp);
						else
							SEEdir[from][target][occ]=-1;
						/*if(from==19 && target==10 && occ==0x26)
						{
							printBitBoard("temp",temp);
							printf("%d\n",SEEdir[from][target][occ]);
						}*/
					}
				}
				else if(ROW(from)==ROW(target))
				{
					if(COL(from)<COL(target))
					{
						ray[target][from][occ]=temp=minus1[from]&rankmoves[from][occ];
						if(temp)
							SEEdir[from][target][occ]=FirstOne(temp);
						else
							SEEdir[from][target][occ]=-1;
					}
					else if(COL(from)==COL(target))
					{
						ray[target][from][occ]=U64EMPTY;
						SEEdir[from][target][occ]=-1; //empty
					}
					else
					{
						ray[target][from][occ]=temp=plus1[from]&rankmoves[from][occ];
						if(temp)
							SEEdir[from][target][occ]=LastOne(temp);
						else
							SEEdir[from][target][occ]=-1;
					}
				}
				else
				{
					if(COL(from)<COL(target))
					{
						ray[target][from][occ]=temp=minus9[from]&a1h8moves[from][occ];
						if(temp)
							SEEdir[from][target][occ]=FirstOne(temp);
						else
							SEEdir[from][target][occ]=-1;
					}
					else if(COL(from)==COL(target))
					{
						ray[target][from][occ]=temp=minus8[from]&filemoves[from][occ];
						if(temp)
							SEEdir[from][target][occ]=FirstOne(temp);
						else
							SEEdir[from][target][occ]=-1;
					}
					else
					{
						ray[target][from][occ]=temp=minus7[from]&h1a8moves[from][occ];
						if(temp)
							SEEdir[from][target][occ]=FirstOne(temp);
						else
							SEEdir[from][target][occ]=-1;
					}
				}
			}
}

/*generateSEEocc()
 *generates the occupancy function pointers for SEE
 */
void generateSEEocc()
{
	char i,j;
	for(i=0;i<64;i++) //from
		for(j=i+1;j<64;j++) //target
			occupancy[i][j]=occupancy[j][i]=&SEEoccdummy;
	for(i=0;i<64;i++) //from
		for(j=i+1;j<64;j++) //target
		{
			if(isDiagonal(i,j))
			{
				if((j-i)%9==0)
				{
					occupancy[i][j]=occupancy[j][i]=&SEEocca1h8;
					continue;
				}
				if((j-i)%7==0)
				{
					occupancy[i][j]=occupancy[j][i]=&SEEocch1a8;
					continue;
				}
				continue;
			}
			else //rank/file
			{
				if(ROW(j)==ROW(i))
				{
					occupancy[i][j]=occupancy[j][i]=&SEEoccrank;
					continue;
				}
				if(COL(j)==COL(i))
				{
					occupancy[i][j]=occupancy[j][i]=&SEEoccfile;
					continue;
				}
			}
		}
}

/*generateSEEpiece()
 *generates the SEE piece which has a bishop if it is diagonal or a rook if it isn't
 */
void generateSEEpiece()
{
	char i,j;
	for(i=0;i<64;i++)
		for(j=0;j<64;j++)
		{
			if(isDiagonal(i,j))
				SEEpiece[i][j]=B;
			else
				SEEpiece[i][j]=R;
		}
}

/*generateKingStopsPasser()
 *generates the kingStopsPasser[64][2] array
 */
void generateKingStopsPasser()
{
	int i,j,k,l;
	U64 tempWHITE, tempBLACK;
	for(i=0;i<64;i++)
	{
		tempWHITE=toBit[i];
		tempBLACK=toBit[i];

		tempWHITE=fillUp2(tempWHITE);
		tempBLACK=fillDown2(tempBLACK);

		k=popCount(tempWHITE);
		l=popCount(tempBLACK);

		for(j=1;j<k && ROW(i) == ROW (i+j);j++)
			tempWHITE|=tempWHITE<<1;
		for(j=1;j<l && ROW(i) == ROW (i+j);j++)
			tempBLACK|=tempBLACK<<1;


		for(j=1;j<k && ROW(i) == ROW (i-j);j++)
			tempWHITE|=tempWHITE>>1;
		for(j=1;j<l && ROW(i) == ROW (i-j);j++)
			tempBLACK|=tempBLACK>>1;

		kingStopsWHITEPasser[i][0]=tempWHITE;
		kingStopsBLACKPasser[i][0]=tempBLACK;

		tempWHITE|=tempWHITE>>8;
		tempBLACK|=tempBLACK<<8;

		if(ROW(i) == ROW(i+k+1))
			tempWHITE|=tempWHITE<<1;
		if(ROW(i) == ROW(i+l+1))
			tempBLACK|=tempBLACK<<1;

		if(ROW(i) == ROW(i-k-1))
			tempWHITE|=tempWHITE>>1;
		if(ROW(i) == ROW(i-l-1))
			tempBLACK|=tempBLACK>>1;

		kingStopsWHITEPasser[i][1]=tempWHITE;
		kingStopsBLACKPasser[i][1]=tempBLACK;
	}
	for(i=8;i<16;i++)
	{
		kingStopsWHITEPasser[i][0]=kingStopsWHITEPasser[i+8][0];
		kingStopsWHITEPasser[i][1]=kingStopsWHITEPasser[i+8][1];
	}
	for(i=48;i<56;i++)
	{
		kingStopsBLACKPasser[i][0]=kingStopsBLACKPasser[i-8][0];
		kingStopsBLACKPasser[i][1]=kingStopsBLACKPasser[i-8][1];
	}
}

/*generateDistance()
 *generates the distance[64][64] array
 */
void generateDistance()
{
	int i,j;
	for(i=0;i<64;i++)
		for(j=0;j<64;j++)
		{
			int dRow=ROW(j)-ROW(i);
			int dCol=COL(j)-COL(i);
			if(dRow<0)
				dRow=-dRow;
			if(dCol<0)
				dCol=-dCol;
			if(dRow<dCol)
				distance[i][j]=dCol;
			else
				distance[i][j]=dRow;
		}
}